#include "ftslidebutton.h"

FTSlideButton::FTSlideButton(Qt::Orientation o,
                             FTControls::IconSize s,
                             QWidget *parent) :
QWidget(parent)
{
    setOrientation( o );
    iconSize = FTControls::iconSize( s );
    selectedState = -1;
}

QSize FTSlideButton::sizeHint() const
{
    int padding = FTControls::defaultPadding();
    if ( _orientation == Qt::Horizontal )
        return QSize( states.count() * iconSize.width() + padding*2+2,
                      iconSize.height() + padding*2+2 );
    else
        return QSize( iconSize.width() + padding*2+2,
                      states.count() * iconSize.height() + padding*2+2);
}

QSize FTSlideButton::minimumSizeHint() const
{
    return sizeHint();
}

void FTSlideButton::paintEvent(QPaintEvent *)
{
    int padding = FTControls::defaultPadding();
    QPalette palette = QApplication::palette();
    QPainter painter(this);
    palette.setCurrentColorGroup( FT_COLOR_GROUP );

    QRect selectedRect;
    QRect iconRect = QRect( QPoint(padding+1,padding+1), iconSize );
    QBrush fillerBrush = palette.brush( QPalette::Highlight );

    foreach (int state, states.keys() )
    {
        const QIcon& icon = states.value( state );
        if ( state == selectedState )
        {
            selectedRect = iconRect.adjusted( -padding, -padding,
                                               padding, padding );
            painter.fillRect( iconRect, fillerBrush );
        }
        icon.paint(&painter, iconRect);
        if ( _orientation == Qt::Horizontal )
            iconRect.translate( iconSize.width(), 0);
        else
            iconRect.translate( 0, iconSize.height() );
    }

    if ( selectedRect.isValid() )
    {
        if ( moving )
        {
            if ( _orientation == Qt::Vertical )
                selectedRect.translate(0, mouse_delta.y() );
            else if ( _orientation == Qt::Horizontal )
                selectedRect.translate( mouse_delta.x(), 0 );
        }
        QPen pen = palette.color( QPalette::HighlightedText );
        pen.setWidth( padding );
        pen.setJoinStyle( Qt::RoundJoin );
        painter.setPen( pen );
        painter.drawRect( selectedRect );
    }
}

void FTSlideButton::mousePressEvent(QMouseEvent * ev)
{
    mouse_start = ev->pos();
    mouse_delta = QPoint(0,0);
    moving = true;
}

void FTSlideButton::mouseReleaseEvent(QMouseEvent *)
{
    int stateCount = -1;
    moving = false;
    // Calculate how many steps...
    if ( _orientation == Qt::Vertical )
        stateCount = (mouse_start.y() + mouse_delta.y()) / iconSize.height();
    else if ( _orientation == Qt::Horizontal )
        stateCount = (mouse_start.x() + mouse_delta.x()) / iconSize.width();
    else
        return;
    // Ensure this is a valid number of steps
    stateCount = qBound( 0, stateCount, states.count()-1 );
    // Step all the states until the right one is found,,,
    foreach (int state, states.keys() )
    {
        // Is the last step?
        if ( stateCount == 0 )
        {   // Is different from currently selected state?
            if ( state != selectedState )
            {
                selectedState = state;
                update();
                emit stateSet( selectedState );
                return;
            }
        }
        stateCount--;
    }
}

void FTSlideButton::mouseMoveEvent(QMouseEvent * ev)
{
    if ( moving )
    {
        mouse_delta = ev->pos() - mouse_start;
        update();
    }
}

void FTSlideButton::setOrientation(Qt::Orientation o)
{
    if ( o == Qt::Horizontal )
    {
        _orientation = o;
        setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
    }
    else if ( o == Qt::Vertical )
    {
        _orientation = o;
        setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
    }
    update();
}

void FTSlideButton::addState( int s, const QIcon& i )
{
    if ( states.contains( s ) )
        return;
    states.insert( s, i );
    if ( selectedState == -1 )
        selectedState = s;
    update();
}

void FTSlideButton::setState(int s)
{
    if ( !states.contains(s))
        return;
    selectedState = s;
    update();
}
